<!--
 * @Author: Wushiqi
 * @Descripttion: 浅拷贝和深拷贝
 * @Date: 2021-04-27 10:02:44
 * @LastEditor: Wushiqi
 * @LastEditTime: 2021-05-08 15:59:33
-->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>
    // 浅拷贝 - 第一层变化不会影响，第二层变化会影响
    const obj = {
      name: 'we',
      like: {
        color: 'pink'
      },
      hab: ['game', 'singing', 'eat']
    }
    const arr = [1, 2, 3, [4]]
    // 第一种 直接把对象的值拷贝到另一个对象
    function shallowCopy(params) {
      // 先区分基本数据类型和引用数据类型
      if (typeof params === 'object') {
        const typeStr = Object.prototype.toString.call(params) // [object Array]
        const type = typeStr.replace(/(\[|\]|object)/g, '').trim() // Array
        let obj = type === 'Array' ? [] : {}
        for (let v in params) {
          obj[v] = params[v]
        }
        return obj
      } else {
        return params
      }
    }
    const copyObj1 = shallowCopy(obj)
    copyObj1.name = 'aaa' // 两个name不一样
    copyObj1.like.color = 'red' // 两个like一样，里面的color一样

    // 第二种 ES6
    const copyObj2 = { ...obj }
    copyObj2.name = 'ws' // 两个name不一样
    copyObj2.hab.push('jump') // 两个hab一样

    // 第三种 Object.assign()
    const copyObj3 = Object.assign({}, obj)
    copyObj3.name = '112' // 两个name不一样
    copyObj3.hab.splice(1, 1) // 两个hab一样

    const copyArr2 = shallowCopy(arr)
    copyArr2[3].push(8) // 两个都是[1, 2, 3, [4, 8]]
    // console.log(arr, copyArr2);


    // 深拷贝
    // 先自己写一个判断数据类型的方法
    function typeOf(param) {
      const res = Object.prototype.toString.call(param).replace(/(\[|\]|object)/g, '').trim().toLowerCase()
      return res
    }
    // 手写深克隆
    function deepClone(obj) {
      // 首先判断参数是基本数据类型还是引用数据类型
      if (typeOf(obj) === 'object' || typeOf(obj) === 'array') { // 引用数据类型
        // 进一步判断是对象还是数组
        let newObj = typeOf(obj) === 'object' ? {} : []
        for (let k in obj) {
          if (typeOf(obj[k]) === 'object' || typeOf(obj[k]) === 'array') {
            newObj[k] = deepClone(obj[k]) // 递归克隆
          } else {
            newObj[k] = obj[k]
          }
        }
        return newObj
      } else { // 基本数据类型
        // 直接返回原数据
        return obj
      }
    }
    const decoObj1 = deepClone(obj)
    decoObj1.hab.push('singing') // 两个hab内容不一样
    decoObj1.like.color = 'blue' // 两个like里的color不一样

    const decoArr = deepClone(arr)
    decoArr[3].push(99) // 两个不一样
    console.log(arr, decoArr);
  </script>
</body>
</html>